package com.lijiajia.cloud.resource.sys.config.security;

import com.lijiajia.cloud.common.security.publiser.AuthenticationLogApplicationEventPublisher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;

/**
 * 安全 配置
 *
 * @author lijiajia
 * @since 2019-05-29
 */
@Configuration
public class SecurityConfiguration {

	/**
	 * 配置 安全表达式处理器
	 */
	@Bean
	public SecurityExpressionHandler<FilterInvocation> expressionHandler(ApplicationContext context) {
		DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler();
		expressionHandler.setApplicationContext(context);
		return expressionHandler;
	}


	/**
	 * 配置 认证事件发布者
	 */
	@Bean
	AuthenticationEventPublisher authenticationEventPublisher() {
		AuthenticationLogApplicationEventPublisher applicationEventPublisher = new AuthenticationLogApplicationEventPublisher();
		return new DefaultAuthenticationEventPublisher(applicationEventPublisher);
	}

	/**
	 * SpEL表达式->URL授权 配置
	 */
	@Configuration
	public class SecurityExpressionConfiguration {

		@Bean
		public ExpressionUrlAuthorizationConfigurer<HttpSecurity> expressionUrlAuthorizationConfigurer(
			ApplicationContext context,
			SecurityExpressionHandler<FilterInvocation> expressionHandler) {
			ExpressionUrlAuthorizationConfigurer<HttpSecurity> configurer = new ExpressionUrlAuthorizationConfigurer<>(context);
			configurer.getRegistry()
				.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
				.antMatchers("/health/**").permitAll()
				// .antMatchers("/test").denyAll()
				.expressionHandler(expressionHandler);
			return configurer;
		}
	}
}
